﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Xpo = DevExpress.Xpo;
using Liekhus.TimeTracker.Module.Web.Providers;

namespace Liekhus.TimeTracker.MVC.Web.Controllers
{
    public abstract class BaseXpoController<T> : Controller
        where T : Xpo.XPBaseObject
    {
        protected virtual Xpo.XPQuery<T> FilterItems(Xpo.XPQuery<T> items)
        {
            return items;
        }

        public virtual ActionResult Index()
        {
            using (Xpo.Session session = XpoConnectionHelper.GetSession<T>())
            {
                Xpo.XPQuery<T> items = FilterItems(new Xpo.XPQuery<T>(session));
                ViewData.Model = (from i in items
                                  select i).ToList<T>();
            }

            return View();
        }

        public virtual ActionResult Details(Guid oid)
        {
            using (Xpo.Session session = XpoConnectionHelper.GetSession<T>())
            {
                ViewData.Model = session.GetObjectByKey<T>(oid);
            }
            return View();
        }

        public virtual ActionResult Create()
        {
            using (Xpo.Session session = XpoConnectionHelper.GetSession<T>())
            {
                ViewData.Model = Activator.CreateInstance(typeof(T), new object[] { session });                
            }
            return View();
        } 

        //
        // POST: /Task/Create

        [HttpPost]
        public virtual ActionResult Create(T item)
        {
            try
            {
                item.Save();
                return RedirectToAction("Index");
            }
            catch(Exception ex)
            {
            //    item.Session.RollbackTransaction();
                ViewData.Model = item;
                ViewData.ModelState.AddModelError("CreateError", ex);
                return View();
            }
        }
        
        //
        // GET: /Task/Edit/5

        public virtual ActionResult Edit(Guid oid)
        {
            return Details(oid);
        }

        //
        // POST: /Task/Edit/5

        public abstract void MapObjectPersistence(T newObject, T oldObject);

        [HttpPost]
        public virtual ActionResult Edit(Guid oid, T item)
        {
            try
            {
                T persisted = XpoConnectionHelper.GetSession<T>().GetObjectByKey<T>(oid);
                MapObjectPersistence(persisted, item);
                persisted.Save();
 
                return RedirectToAction("Index");
            }
            catch (Exception ex)
            {
                ViewData.Model = item;
                ViewData.ModelState.AddModelError("EditError", ex);
                return View();
            }
        }

        //
        // GET: /Task/Delete/5

        public virtual ActionResult Delete(Guid oid)
        {
            return Details(oid);
        }

        //
        // POST: /Task/Delete/5

        [HttpPost]
        public virtual ActionResult Delete(Guid oid, T item)
        {
            try
            {
                T persisted = XpoConnectionHelper.GetSession<T>().GetObjectByKey<T>(oid);
                persisted.Delete();
                persisted.Save();
 
                return RedirectToAction("Index");
            }
            catch (Exception ex)
            {
                ViewData.Model = item;
                ViewData.ModelState.AddModelError("DeleteError", ex);
                return View();
            }
        }
    }
}

